package com.alex.common.tools;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

public abstract class DateUtils {

	public static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";

	private static final int dayArray[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30,
			31, 30, 31 };

	public static String getDateSecondFormat(Date date) {
		return (new SimpleDateFormat(DEFAULT_FORMAT)).format(date);
	}

	public static String getDateYearMonthChinese(Date date) {
		return (new SimpleDateFormat("yyyy年MM月")).format(date);
	}

	public static int getDateHour(Date date) {
		return Integer.parseInt((new SimpleDateFormat("HH")).format(date));
	}

	public static int getDateDay(Date date) {
		return Integer.parseInt((new SimpleDateFormat("dd")).format(date));
	}

	public static int getDateMonth(Date date) {
		return Integer.parseInt((new SimpleDateFormat("MM")).format(date));
	}

	public static void main(String[] args) {
		System.out.println(getDateMonth(new Date()));
	}

	// -----------------------unused--------

	public static java.util.Date StringToDate(String dateString, String partten) {
		SimpleDateFormat df = new SimpleDateFormat(partten);
		return df.parse(dateString, new ParsePosition(0));
	}

	public static String toString(java.util.Date date, String partten) {
		if (date == null) {
			return "";
		} else {
			SimpleDateFormat df = new SimpleDateFormat(partten);
			return df.format(date);
		}
	}

	/**/
	public static java.util.Date getGBDateFrmString(String dateValue)
			throws ParseException {
		Locale locale = Locale.SIMPLIFIED_CHINESE;
		DateFormat df = DateFormat.getDateInstance(2, locale);
		return df.parse(dateValue);
	}

	public static synchronized Calendar getCalendar() {
		return GregorianCalendar.getInstance();
	}

	public static synchronized int getLastDayOfMonth(int month) {
		if (month < 1 || month > 12)
			return -1;
		int retn = 0;
		if (month == 2) {
			if (isLeapYear())
				retn = 29;
			else
				retn = dayArray[month - 1];
		} else {
			retn = dayArray[month - 1];
		}
		return retn;
	}

	public static synchronized int getLastDayOfMonth(int year, int month) {
		if (month < 1 || month > 12)
			return -1;
		int retn = 0;
		if (month == 2) {
			if (isLeapYear(year))
				retn = 29;
			else
				retn = dayArray[month - 1];
		} else {
			retn = dayArray[month - 1];
		}
		return retn;
	}

	public static synchronized boolean isLeapYear() {
		Calendar cal = Calendar.getInstance();
		int year = cal.get(1);
		return isLeapYear(year);
	}

	public static synchronized boolean isLeapYear(int year) {
		if (year % 400 == 0)
			return true;
		if (year % 4 == 0)
			return year % 100 != 0;
		else
			return false;
	}

	public static synchronized boolean isLeapYear(java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		int year = gc.get(1);
		return isLeapYear(year);
	}

	public static synchronized boolean isLeapYear(Calendar gc) {
		int year = gc.get(1);
		return isLeapYear(year);
	}

	public static synchronized java.util.Date getPreviousWeekDay(
			java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		return getPreviousWeekDay(((Calendar) (gc)));
	}

	public static synchronized java.util.Date getPreviousWeekDay(Calendar gc) {
		switch (gc.get(7)) {
		case 2: // '\002'
			gc.add(5, -3);
			break;

		case 1: // '\001'
			gc.add(5, -2);
			break;

		default:
			gc.add(5, -1);
			break;
		}
		return gc.getTime();
	}

	public static synchronized java.util.Date getNextWeekDay(java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		switch (gc.get(7)) {
		case 6: // '\006'
			gc.add(5, 3);
			break;

		case 7: // '\007'
			gc.add(5, 2);
			break;

		default:
			gc.add(5, 1);
			break;
		}
		return gc.getTime();
	}

	public static synchronized Calendar getNextWeekDay(Calendar gc) {
		switch (gc.get(7)) {
		case 6: // '\006'
			gc.add(5, 3);
			break;

		case 7: // '\007'
			gc.add(5, 2);
			break;

		default:
			gc.add(5, 1);
			break;
		}
		return gc;
	}

	public static synchronized java.util.Date getLastDayOfNextMonth(
			java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(getNextMonth(gc.getTime()));
		gc.setTime(getLastDayOfMonth(gc.getTime()));
		return gc.getTime();
	}

	public static synchronized java.util.Date getLastDayOfNextWeek(
			java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(getNextWeek(gc.getTime()));
		gc.setTime(getLastDayOfWeek(gc.getTime()));
		return gc.getTime();
	}

	public static synchronized java.util.Date getFirstDayOfNextMonth(
			java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(getNextMonth(gc.getTime()));
		gc.setTime(getFirstDayOfMonth(gc.getTime()));
		return gc.getTime();
	}

	public static synchronized Calendar getFirstDayOfNextMonth(Calendar gc) {
		gc.setTime(getNextMonth(gc.getTime()));
		gc.setTime(getFirstDayOfMonth(gc.getTime()));
		return gc;
	}

	public static synchronized java.util.Date getFirstDayOfNextWeek(
			java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(getNextWeek(gc.getTime()));
		gc.setTime(getFirstDayOfWeek(gc.getTime()));
		return gc.getTime();
	}

	public static synchronized Calendar getFirstDayOfNextWeek(Calendar gc) {
		gc.setTime(getNextWeek(gc.getTime()));
		gc.setTime(getFirstDayOfWeek(gc.getTime()));
		return gc;
	}

	public static synchronized java.util.Date getNextMonth(java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(2, 1);
		return gc.getTime();
	}

	public static synchronized Calendar getNextMonth(Calendar gc) {
		gc.add(2, 1);
		return gc;
	}

	public static synchronized java.util.Date getNextDay(java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(5, 1);
		return gc.getTime();
	}

	public static synchronized Calendar getNextDay(Calendar gc) {
		gc.add(5, 1);
		return gc;
	}

	public static synchronized java.util.Date getNextWeek(java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(5, 7);
		return gc.getTime();
	}

	public static synchronized Calendar getNextWeek(Calendar gc) {
		gc.add(5, 7);
		return gc;
	}

	public static synchronized java.util.Date getLastDayOfWeek(
			java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		switch (gc.get(7)) {
		case 1: // '\001'
			gc.add(5, 6);
			break;

		case 2: // '\002'
			gc.add(5, 5);
			break;

		case 3: // '\003'
			gc.add(5, 4);
			break;

		case 4: // '\004'
			gc.add(5, 3);
			break;

		case 5: // '\005'
			gc.add(5, 2);
			break;

		case 6: // '\006'
			gc.add(5, 1);
			break;

		case 7: // '\007'
			gc.add(5, 0);
			break;
		}
		return gc.getTime();
	}

	public static synchronized java.util.Date getFirstDayOfWeek(
			java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		switch (gc.get(7)) {
		case 1: // '\001'
			gc.add(5, 0);
			break;

		case 2: // '\002'
			gc.add(5, -1);
			break;

		case 3: // '\003'
			gc.add(5, -2);
			break;

		case 4: // '\004'
			gc.add(5, -3);
			break;

		case 5: // '\005'
			gc.add(5, -4);
			break;

		case 6: // '\006'
			gc.add(5, -5);
			break;

		case 7: // '\007'
			gc.add(5, -6);
			break;
		}
		return gc.getTime();
	}

	public static synchronized Calendar getFirstDayOfWeek(Calendar gc) {
		switch (gc.get(7)) {
		case 1: // '\001'
			gc.add(5, 0);
			break;

		case 2: // '\002'
			gc.add(5, -1);
			break;

		case 3: // '\003'
			gc.add(5, -2);
			break;

		case 4: // '\004'
			gc.add(5, -3);
			break;

		case 5: // '\005'
			gc.add(5, -4);
			break;

		case 6: // '\006'
			gc.add(5, -5);
			break;

		case 7: // '\007'
			gc.add(5, -6);
			break;
		}
		return gc;
	}

	public static synchronized java.util.Date getLastDayOfMonth(
			java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		switch (gc.get(2)) {
		case 0: // '\0'
			gc.set(5, 31);
			break;

		case 1: // '\001'
			gc.set(5, 28);
			break;

		case 2: // '\002'
			gc.set(5, 31);
			break;

		case 3: // '\003'
			gc.set(5, 30);
			break;

		case 4: // '\004'
			gc.set(5, 31);
			break;

		case 5: // '\005'
			gc.set(5, 30);
			break;

		case 6: // '\006'
			gc.set(5, 31);
			break;

		case 7: // '\007'
			gc.set(5, 31);
			break;

		case 8: // '\b'
			gc.set(5, 30);
			break;

		case 9: // '\t'
			gc.set(5, 31);
			break;

		case 10: // '\n'
			gc.set(5, 30);
			break;

		case 11: // '\013'
			gc.set(5, 31);
			break;
		}
		if (gc.get(2) == 1 && isLeapYear(gc.get(1)))
			gc.set(5, 29);
		return gc.getTime();
	}

	public static synchronized Calendar getLastDayOfMonth(Calendar gc) {
		switch (gc.get(2)) {
		case 0: // '\0'
			gc.set(5, 31);
			break;

		case 1: // '\001'
			gc.set(5, 28);
			break;

		case 2: // '\002'
			gc.set(5, 31);
			break;

		case 3: // '\003'
			gc.set(5, 30);
			break;

		case 4: // '\004'
			gc.set(5, 31);
			break;

		case 5: // '\005'
			gc.set(5, 30);
			break;

		case 6: // '\006'
			gc.set(5, 31);
			break;

		case 7: // '\007'
			gc.set(5, 31);
			break;

		case 8: // '\b'
			gc.set(5, 30);
			break;

		case 9: // '\t'
			gc.set(5, 31);
			break;

		case 10: // '\n'
			gc.set(5, 30);
			break;

		case 11: // '\013'
			gc.set(5, 31);
			break;
		}
		if (gc.get(2) == 1 && isLeapYear(gc.get(1)))
			gc.set(5, 29);
		return gc;
	}

	public static synchronized java.util.Date getFirstDayOfMonth(
			java.util.Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.set(5, 1);
		return gc.getTime();
	}

	public static synchronized Calendar getFirstDayOfMonth(Calendar gc) {
		gc.set(5, 1);
		return gc;
	}

	public static synchronized String toString(java.util.Date theDate,
			DateFormat theDateFormat) {
		if (theDate == null)
			return "";
		else
			return theDateFormat.format(theDate);
	}

	public static long marginMillisecond(java.util.Date nowDate,
			java.util.Date preDate) {
		return nowDate.getTime() - preDate.getTime();
	}

	private static final long DAY = 1000 * 60 * 60 * 24;

	public static long marginYear(java.util.Date nowDate, java.util.Date preDate) {
		long ms = marginMillisecond(nowDate, preDate);
		return ms / DAY / 365;
	}
}
